package com.kingsoft.dc.khaos.extender.meta.model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.math.NumberUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.alibaba.fastjson.serializer.SerializerFeature.WriteMapNullValue;

/**
 * Created by jing on 19/6/25.
 */
public class MetaParams implements Serializable {
    private static final long serialVersionUID = 1L;

    private String env;
    private int projectId;
    private String projectName = "";
    private String dsType;
    private int dsId;
    private String dsName;
    private String dbName;
    private String tblName;
    private String tblType;
    private String privilege;
    private List<String> privSet;

    //作业所属的项目ID
    private int jobProjectId;

    //作业所属的项目名称
    private String jobProjectName = "";


    public List<String> getPrivSet() {
        return privSet;
    }

    public void setPrivSet(List<String> privSet) {
        this.privSet = privSet;
    }

    public MetaParams() {

    }

    public enum TABLE_TYPE {
        FILE, RELATIONAL, INFLUXDB, TOPIC, HDFS, SQLSERVER, PGSQL,MASSIVELY_PARALLEL_PROCESSING
    }

    public enum PRIVILEGE_TYPE {
        read, readAndWrite
    }

    /**
     * metaParamJson:{"ds_type": "mpp","ds_id": "2","ds_name": "mpp001","user_id": "1","project_id": "6"}
     *
     * @param metaParamJson
     */
    public MetaParams(String metaParamJson) {
        Map<String, Object> metaMap = JSON.parseObject(metaParamJson, Map.class);
        this.dsType = (String) metaMap.get("ds_type");
        this.dsId = metaMap.get("ds_id") == null ? 0 : NumberUtils.toInt(metaMap.get("ds_id").toString(), 0);
        this.dsName = (String) metaMap.get("ds_name");
        this.projectId = metaMap.get("project_id") == null ? 0 : NumberUtils.toInt(metaMap.get("project_id").toString(), 0);
        //this.projectName = metaMap.containsKey("project_name") ? String.valueOf(metaMap.get("project_name")) : null;
    }

    /**
     * 根据dbName,tblName 构建[获取有读写权限数据源信息]请求参数
     *
     * @param env
     * @param dbName
     * @param tblName
     * @return
     */
    public MetaParams buildWriteDatasourceParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.privilege = PRIVILEGE_TYPE.readAndWrite.name();
        return this;
    }

    /**
     * 根据dbName,tblName 构建[获取有读权限数据源信息]请求参数
     *
     * @param env
     * @param dbName
     * @param tblName
     * @return
     */
    public MetaParams buildReadDatasourceParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.privilege = PRIVILEGE_TYPE.read.name();
        return this;
    }

    /**
     * 根据dsId 构建[获取有读写权限数据源信息]请求参数
     *
     * @param env
     * @param dsId
     * @return
     */
    public MetaParams buildWriteDatasourceParams(String env, int dsId) {
        this.env = env;
        this.dsId = dsId;
        this.privilege = PRIVILEGE_TYPE.readAndWrite.name();
        return this;
    }

    /**
     * 根据dsId,构建[获取有读权限数据源信息]请求参数
     *
     * @param env
     * @param dsId
     * @return
     */
    public MetaParams buildReadDatasourceParams(String env, int dsId) {
        this.env = env;
        this.dsId = dsId;
        this.privilege = PRIVILEGE_TYPE.read.name();
        return this;
    }


    /**
     * 根据dsName 构建[获取有读写权限数据源信息]请求参数
     *
     * @param env
     * @param dsName
     * @return
     */
    public MetaParams buildWriteDatasourceParams(String env, String dsName) {
        this.env = env;
        this.dsName = dsName;
        this.privilege = PRIVILEGE_TYPE.readAndWrite.name();
        return this;
    }

    /**
     * 根据dsName,构建[获取有读权限数据源信息]请求参数
     *
     * @param env
     * @param dsName
     * @return
     */
    public MetaParams buildReadDatasourceParams(String env, String dsName) {
        this.env = env;
        this.dsName = dsName;
        this.privilege = PRIVILEGE_TYPE.read.name();
        return this;
    }

    public MetaParams buildDatabaseParams(String env, String dbName) {
        this.env = env;
        this.dbName = dbName;
        return this;
    }

    public MetaParams buildHDFSTableParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.HDFS.name();
        return this;
    }

    public MetaParams buildFileTableParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.FILE.name();
        return this;
    }

    public MetaParams buildTableParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.RELATIONAL.name();
        return this;
    }

    public MetaParams buildMppTableParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.MASSIVELY_PARALLEL_PROCESSING.name();
        return this;
    }

    /**
     * 通过灵活指定TABLE_TYPE来构建表参数
     *
     * @param env
     * @param dbName
     * @param tblName
     * @param table_type 表类型
     * @return
     * @author fanshengli
     */
    public MetaParams buildTableParams(String env, String dbName, String tblName, TABLE_TYPE table_type) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = table_type.name();
        return this;
    }

    public MetaParams buildInfluxParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.INFLUXDB.name();
        return this;
    }

    public MetaParams buildTopicParams(String env, String tblName) {
        this.env = env;
//        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = TABLE_TYPE.TOPIC.name();
        return this;
    }

    public MetaParams buildNosqlTableParams(String env, String dbName, String tblName) {
        this.env = env;
        this.dbName = dbName;
        this.tblName = tblName;
        this.tblType = "";
        return this;
    }

    public MetaParams buildAuthParams(String env, String jobProjectId, String dbName, String tblName, List<String> privSet) {
        this.env = env.toUpperCase();
        this.dbName = dbName;
        this.tblName = tblName;
//        this.dsId = Integer.parseInt(metaMap.get("ds_id"));
        this.jobProjectId = Integer.parseInt(jobProjectId);
        this.privSet = privSet;
        return this;
    }


    public MetaParams buildAuthParams(String env, String jobProjectId, String jobProjectName, String dbName, String tblName, List<String> privSet) {
        this.env = env.toUpperCase();
        this.dbName = dbName;
        this.tblName = tblName;
        this.jobProjectId = Integer.parseInt(jobProjectId);
        //this.jobProjectName = jobProjectName;
        this.privSet = privSet;
        return this;
    }


    public MetaParams appendEnv(String env) {
        this.env = env;
        return this;
    }

    public MetaParams appendDbName(String dbName) {
        this.dbName = dbName;
        return this;
    }

    public MetaParams appendTblName(String tblName) {
        this.tblName = tblName;
        return this;
    }

    public MetaParams appendTblType(String tblType) {
        this.tblType = tblType;
        return this;
    }

    public MetaParams appendPrivilege(String privilege) {
        this.privilege = privilege;
        return this;
    }

    public String getDatasourceParams() {
//        return String.format("{\"env\":\"%s\",\"projectId\":%d,\"projectName\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\", \"dbName\":\"%s\",\"tblName\":\"%s\",\"privilege\":\"%s\"}",
//                env, jobProjectId, jobProjectName, dsId, dsName, dbName, tblName, privilege);
        JSONObject var1 = new JSONObject();
        var1.put("env", env.toUpperCase());
        if (jobProjectId > 0) {
            var1.put("projectId", jobProjectId);
        }
        //var1.put("projectName", jobProjectName);
        if (dsId > 0) {
            var1.put("dsId", dsId);
        }
        var1.put("dsName", dsName);
        var1.put("dbName", dbName);
        var1.put("tblName", tblName);
        var1.put("privilege", privilege);
        return var1.toJSONString();
    }


    public String getDsIdParams() {
        return String.format("{\"env\":\"%s\",\"dsIds\":[%d],\"privilege\":\"%s\"}",
                env, dsId, privilege);
    }

    public String getDsNameParams() {
        return String.format("{\"env\":\"%s\",\"dsNames\":[\"%s\"],\"privilege\":\"%s\"}",
                env, dsName, privilege);
    }

    /**
     * manageMeta: true 是托管数据源，false 查询非托管和托管数据源
     */
    public String getDatasourceListParams() {
        return String.format("{\"dataTypes\":[\"%s\"],\"manageMeta\":false,\"dsNames\":[\"%s\"]}",
                dsType, dsName);
    }

    /**
     * @return
     */
    public String getDatabaseParams() {
//        if (projectId > 0) {
//            return String.format("{\"env\":\"%s\",\"projectId\":%s,\"projectName\":\"%s\", \"dataType\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"pageParam\":{\"page\":1,\"pageSize\":1}}",
//                    env, projectId, projectName, dsType, dsId, dsName, dbName, tblName, privilege);
//        } else {
//            return String.format("{\"env\":\"%s\",\"dataType\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"pageParam\":{\"page\":1,\"pageSize\":1}}",
//                    env, dsType, dsId, dsName, dbName, tblName, privilege);
//        }
//        System.out.println(String.format("{\"env\":\"%s\",\"projectId\":%s,\"projectName\":\"%s\", \"dataType\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"pageParam\":{\"page\":1,\"pageSize\":1}}",
//                    env, projectId, projectName, dsType, dsId, dsName, dbName, tblName, privilege));
        Map<String, Object> var1 = new HashMap<>();
        var1.put("env", env.toUpperCase());
        /* 20200724 取消传递projectId 适配导入导出
        if (projectId > 0) {
            var1.put("projectId", String.valueOf(projectId));
        }*/
        //var1.put("projectName", projectName);
        var1.put("dataType", dsType);
        var1.put("dsId", dsId);
        var1.put("dsName", dsName);
        var1.put("dbName", dbName);

        Map<String, Object> pagePram = new HashMap<>();
        pagePram.put("page", 1);
        pagePram.put("pageSize", 1);
        var1.put("pageParam", pagePram);
        return JSON.toJSONString(var1, WriteMapNullValue);
    }

    /**
     * @return
     */
    public String getTableParams() {
        Map<String, Object> var1 = new HashMap<>();
        var1.put("env", env.toUpperCase());
        /* 20200724 取消传递projectId 适配导入导出
        if (projectId > 0) {
            var1.put("projectId", projectId);
        }*/
        //var1.put("projectName", projectName);
        if (dsId > 0) {
            var1.put("dsId", dsId);
        }
        var1.put("dsName", dsName);
        var1.put("dbName", dbName);
        var1.put("tblName", tblName);
        var1.put("tblType", tblType);
        return JSON.toJSONString(var1, WriteMapNullValue);
//        if (projectId > 0) {
//            return  String.format("{\"env\":\"%s\",\"projectId\":%d,\"projectName\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"tblName\":\"%s\",\"tblType\":\"%s\",\"pageParam\":{\"page\":1,\"pageSize\":1}}",
//                    env, projectId, projectName, dsId, dsName, dbName, tblName, tblType);
//        } else {
//            return String.format("{\"env\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"tblName\":\"%s\",\"tblType\":\"%s\",\"pageParam\":{\"page\":1,\"pageSize\":1}}",
//                    env, dsId, dsName, dbName, tblName, tblType);
//        }
    }


    /**
     * @return
     */
    public String getTableColumnParams() {
        return getTableParams();
//        if (projectId > 0) {
//            return String.format("{\"env\":\"%s\",\"projectId\":%d,\"projectName\":\"%s\",\"dsId\":%d,\"dsName\":\"%s\", \"dbName\":\"%s\",\"tblName\":\"%s\",\"tblType\":\"%s\"}",
//                    env, projectId, projectName, dsId, dsName, dbName, tblName, tblType);
//        } else {
//            if (dsId > 0 ){
//                return String.format("{\"env\":\"%s\",\"dsId\":%d,\"dbName\":\"%s\",\"tblName\":\"%s\"}",
//                        env, dsId, dbName, tblName);
//            } else {
//                return String.format("{\"env\":\"%s\",\"dsName\":%d,\"dbName\":\"%s\",\"tblName\":\"%s\"}",
//                        env, dsName, dbName, tblName);
//            }
//        }

    }

    /**
     * @return
     */
    public String getAuthParams() {
        Map<String, Object> var1 = new HashMap<>();
        Map<String, Object> projectParam = new HashMap<>();
        if (jobProjectId > 0) {
            projectParam.put("projectId", String.valueOf(jobProjectId));
        }
        //projectParam.put("projectName", jobProjectName);
        var1.put("projectParam", projectParam);
        var1.put("metadataPrivsList", getMetaPrivsList(dbName, tblName, getPrivSet()));
        var1.put("env", env.toUpperCase());
        if (dsId > 0) {
            var1.put("dataSourceId", String.valueOf(dsId));
        }
        var1.put("dataSourceName", dsName);
        return JSON.toJSONString(var1, WriteMapNullValue);
    }

    public List<Map<String, Object>> getMetaPrivsList(String dbName, String tableName, List<String> privSet) {
        List<Map<String, Object>> metaMapList = new ArrayList<>();
        Map<String, Object> metaMap = new HashMap();
        metaMap.put("dbName", dbName);
        metaMap.put("tableName", tableName);
        List<String> newPrivs = new ArrayList<>();
        for (String priv : privSet) {
            newPrivs.add(priv.toUpperCase());
        }
        metaMap.put("privSet", newPrivs);
        metaMapList.add(metaMap);
        return metaMapList;
    }

    /**
     * @return
     */
    public String getTableSplitParams() {
//        return String.format("{\"env\":\"%s\",\"projectId\":%d, \"projectName\":\"%s\", \"dsId\":%d,\"dsName\":\"%s\",\"dbName\":\"%s\",\"tblName\":\"%s\",\"tblType\":\"%s\"}",
//                env, projectId, projectName, dsId, dsName, dbName, tblName, tblType);
        return getTableParams();
    }

    public String getEnv() {
        return env;
    }

    public void setEnv(String env) {
        this.env = env;
    }

    public int getProjectId() {
        return projectId;
    }

    public void setProjectId(int projectId) {
        this.projectId = projectId;
    }

    public int getDsId() {
        return dsId;
    }

    public void setDsId(int dsId) {
        this.dsId = dsId;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    public String getTblName() {
        return tblName;
    }

    public String getDsName() {
        return dsName;
    }

    public void setDsName(String dsName) {
        this.dsName = dsName;
    }


    public void setTblName(String tblName) {
        this.tblName = tblName;
    }

    public String getPrivilege() {
        return privilege;
    }

    public void setPrivilege(String privilege) {
        this.privilege = privilege;
    }

    public String toString() {
        return String.format("{\"env\":%s,\"projectId\":%d,\"projectName\":\"%s\", \"dsId\":%d,\"dsName\":\"%s\", \"dbName\":%s,\"tblName\":%s, \"privilege\":%s",
                env, projectId, projectName, dsId, dsName, dbName, tblName, privilege);
    }

    public String List2String(List<String> list) {
        StringBuffer sb = new StringBuffer();
        for (String s : list) {
            sb.append("\"" + s + "\"");
            sb.append(",");
        }
        return sb.substring(0, sb.lastIndexOf(",")).toUpperCase();
    }

    public String getDsType() {
        return dsType;
    }

    public void setDsType(String dsType) {
        this.dsType = dsType;
    }

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public int getJobProjectId() {
        return jobProjectId;
    }

    public void setJobProjectId(int jobProjectId) {
        this.jobProjectId = jobProjectId;
    }

    public String getJobProjectName() {
        return jobProjectName;
    }

    public void setJobProjectName(String jobProjectName) {
        this.jobProjectName = jobProjectName;
    }
}
